package com.keba.lamp.oauth.controller;

import cloud.tianai.captcha.application.ImageCaptchaApplication;
import cloud.tianai.captcha.application.vo.CaptchaResponse;
import cloud.tianai.captcha.application.vo.ImageCaptchaVO;
import cloud.tianai.captcha.common.constant.CaptchaTypeConstant;
import cloud.tianai.captcha.common.response.ApiResponse;
import cloud.tianai.captcha.validator.common.constant.TrackTypeConstant;
import cloud.tianai.captcha.validator.common.model.dto.ImageCaptchaTrack;
import com.keba.basic.utils.BeanPlusUtil;
import com.keba.lamp.oauth.vo.param.ImageCaptcha;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import com.keba.basic.annotation.response.IgnoreResponseBodyAdvice;
import com.keba.basic.base.R;
import com.keba.basic.exception.BizException;
import com.keba.lamp.oauth.granter.CaptchaTokenGranter;
import com.keba.lamp.oauth.service.CaptchaService;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

import static com.keba.lamp.common.constant.SwaggerConstants.DATA_TYPE_STRING;

/**
 * 验证码服务
 *
 * @author tangyh
 * @version v1.0
 * @date 2022/9/29 5:37 PM
 * @create [2022/9/29 5:37 PM ] [tangyh] [初始创建]
 */
@Slf4j
@RestController
@RequestMapping("/anyTenant")
@AllArgsConstructor
@Tag(name = "验证码")
public class CaptchaController {

    private final CaptchaService captchaService;

    private final ImageCaptchaApplication imageCaptchaApplication;

    /**
     * 验证验证码
     *
     * @param key  验证码唯一uuid key
     * @param code 验证码
     */
    @Operation(summary = "验证验证码是否正确", description = "验证验证码")
    @GetMapping(value = "/checkCaptcha")
    public R<Boolean> checkCaptcha(@RequestParam(value = "key") String key, @RequestParam(value = "code") String code, @RequestParam(value = "templateCode", required = false, defaultValue = CaptchaTokenGranter.GRANT_TYPE) String templateCode) throws BizException {
        return this.captchaService.checkCaptcha(key, templateCode, code);
    }


    @Operation(summary = "验证划块验证码")
    @PostMapping("/check")
    public R<?> checkCaptcha(@RequestBody Data data, HttpServletRequest request) {
        ImageCaptchaTrack imageCaptchaTrack = BeanPlusUtil.toBean(data.data, ImageCaptchaTrack.class);
        ApiResponse<?> response = imageCaptchaApplication.matching(data.getId(), imageCaptchaTrack);
        if (response.isSuccess()) {
            return R.success(Collections.singletonMap("id", data.getId()));
        }
        return R.fail(response.getMsg());
    }

    @lombok.Data
    public static class Data {
        private String id;
        private ImageCaptcha data;
    }



    @Operation(summary = "获取图片验证码", description = "获取图片验证码")


    @Parameters({@Parameter(name = "key", description = "唯一字符串: 前端随机生成一个唯一字符串用于生成验证码，并将key传给后台用于验证", schema = @Schema(type = DATA_TYPE_STRING), in = ParameterIn.QUERY),})
    @GetMapping(value = "/captcha", produces = "image/png")
    @IgnoreResponseBodyAdvice
    public void captcha(@RequestParam(value = "key") String key, HttpServletResponse response) throws IOException {
        this.captchaService.createImg(key, response);
    }

    @RequestMapping("/gen")
    @Operation(summary = "获取划块图片验证码", description = "获取划块图片验证码")
    public R<CaptchaResponse<ImageCaptchaVO>> genCaptcha(HttpServletRequest request, @RequestParam(value = "type", required = false) String type) {
        if (StringUtils.isBlank(type)) {
            type = CaptchaTypeConstant.SLIDER;
        }
        if ("RANDOM".equals(type)) {
            int i = ThreadLocalRandom.current().nextInt(0, 4);
            if (i == 0) {
                type = CaptchaTypeConstant.SLIDER;
            } else if (i == 1) {
                type = CaptchaTypeConstant.CONCAT;
            } else if (i == 2) {
                type = CaptchaTypeConstant.ROTATE;
            } else {
                type = CaptchaTypeConstant.WORD_IMAGE_CLICK;
            }

        }
        return R.success(imageCaptchaApplication.generateCaptcha(type));
    }

    @Operation(summary = "发送短信验证码", description = "发送短信验证码")
    @Parameters({@Parameter(name = "mobile", description = "手机号", schema = @Schema(type = DATA_TYPE_STRING), in = ParameterIn.QUERY), @Parameter(name = "templateCode", description = "模板编码: 在「运营平台」-「消息模板」-「模板标识」配置一个短信模板", schema = @Schema(type = DATA_TYPE_STRING), in = ParameterIn.QUERY),})
    @GetMapping(value = "/sendSmsCode")
    public R<Boolean> sendSmsCode(@RequestParam(value = "mobile") String mobile, @RequestParam(value = "templateCode") String templateCode) {
        return captchaService.sendSmsCode(mobile, templateCode);
    }

    @Parameters({@Parameter(name = "email", description = "邮箱", schema = @Schema(type = DATA_TYPE_STRING), in = ParameterIn.QUERY), @Parameter(name = "templateCode", description = "模板编码: 在「运营平台」-「消息模板」-「模板标识」配置一个邮件模板", schema = @Schema(type = DATA_TYPE_STRING), in = ParameterIn.QUERY),})
    @Operation(summary = "发送邮箱验证码", description = "发送邮箱验证码")
    @GetMapping(value = "/sendEmailCode")
    public R<Boolean> sendEmailCode(@RequestParam(value = "email") String email, @RequestParam(value = "templateCode") String templateCode) {
        return captchaService.sendEmailCode(email, templateCode);
    }

}
